package com.lawliet.example.handler.dicttranslate;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.lawliet.example.annotation.Dict;
import com.lawliet.example.model.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 处理controller返回对象中的字典翻译
 */
@RestControllerAdvice
@Slf4j
public class DictResponseAdvice implements ResponseBodyAdvice<Object> {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     *
     * @param returnType the return type
     * @param converterType the selected converter type
     * @return 返回值为true就会调用beforeBodyWrite方法
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {

        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        translateDictText(body);
        return body;
    }

    /**
     * 对 Result<IPage<T>> 的 records 部分做字典翻译，自动注入 xxxDictText 字段
     */
    public void translateDictText(Object result) {
        if (!(result instanceof Result)) return;
        Object realData = ((Result<?>) result).getResult();
        if (!(realData instanceof IPage)) return;

        IPage<?> page = (IPage<?>) realData;
        List<?> records = page.getRecords();
        List<Map<String, Object>> newRecords = new ArrayList<>();

        for (Object record : records) {
            Map<String, Object> jsonMap = new LinkedHashMap<>();
            Class<?> clazz = record.getClass();

            // 处理当前类及父类字段
            while (clazz != null && clazz != Object.class) {
                for (Field field : clazz.getDeclaredFields()) {
                    field.setAccessible(true);
                    try {
                        // 跳过 @JsonProperty(access = WRITE_ONLY) 的字段
                        JsonProperty jsonProp = field.getAnnotation(JsonProperty.class);
                        if (jsonProp != null && jsonProp.access() == JsonProperty.Access.WRITE_ONLY) {
                            continue;
                        }
                        Object value = field.get(record);
                        String fieldName = field.getName();
                        jsonMap.put(fieldName, value);
                        //时间格式处理
                        JsonFormat datePattern = field.getAnnotation(JsonFormat.class);
                        if(datePattern!=null && value!=null){
                            String pattern = datePattern.pattern();
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
                            jsonMap.put(fieldName,simpleDateFormat.format(value));
                        }
                        // 翻译 @Dict 注解字段
                        Dict dict = field.getAnnotation(Dict.class);
                        if (dict != null && value != null) {
                            String dicCode = dict.dicCode();
                            String text = redisTemplate.opsForValue().get("sys_dict:"+dicCode+":"+value);
                            jsonMap.put(fieldName + "DictText", text);
                        }

                    } catch (IllegalAccessException e) {
                        log.warn("字段访问失败: {}", e.getMessage());
                    }
                }
                clazz = clazz.getSuperclass(); // 支持继承字段
            }

            newRecords.add(jsonMap);
        }

        // 替换原 records
        ((IPage<Object>) page).setRecords((List) newRecords);
    }

}
